package com.quickthumb.game;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Random;

import javax.microedition.khronos.opengles.GL10;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Typeface;
import android.util.Log;
import android.view.MotionEvent;

public class Screen implements UpdateAndDraw {

	public static final int SEED = 0;
	public static final int HOLES_W = 4, HOLES_H = 3;
	public static final float SCREEN_RATIO = 4.f / 3.f;
	public static float HOLE_SIZE, SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_XOFFSET,
			SCREEN_YOFFSET;
	public static float BOARD_SCALE = 0.9f, BOARD_WIDTH, BOARD_HEIGHT,
			BOARD_XOFFSET, BOARD_YOFFSET;

	public static ArrayList<Rat> bucket;
	private static final int POOLSIZE = 100;
	private static final int BUCKET_SIZE = 2;
	public static Rat[] pool = new Rat[POOLSIZE];
	public static int pool_index = 0;
	public static Random random;
	public Player player;
	public static ArrayList<Trap> ActiveTraps = new ArrayList<Trap>();
	public static Block currentBlock = null;

	public static void setSize(int w, int h) {
		// width, height
		int wMatchH = (int) (h * SCREEN_RATIO);
		int hMatchW = (int) (w / SCREEN_RATIO);
		if (wMatchH < w) {
			SCREEN_WIDTH = wMatchH;
			SCREEN_HEIGHT = h;
		} else {
			SCREEN_WIDTH = w;
			SCREEN_HEIGHT = hMatchW;
		}
		// offset
		SCREEN_XOFFSET = (w - SCREEN_WIDTH) / 2;
		SCREEN_YOFFSET = (h - SCREEN_HEIGHT) / 2;
		// scale
		HOLE_SIZE = SCREEN_WIDTH / HOLES_W;
		// board size
		BOARD_WIDTH = BOARD_SCALE * SCREEN_WIDTH;
		BOARD_HEIGHT = BOARD_SCALE * SCREEN_HEIGHT;
		BOARD_XOFFSET = (SCREEN_WIDTH - BOARD_WIDTH) / 2;
		BOARD_YOFFSET = (SCREEN_HEIGHT - BOARD_HEIGHT) / 2;
	}

	@Override
	public void init() {
		random = new Random(SEED);
		// pool
		ArrayList<Rat> lst = new ArrayList<Rat>();
		for (int i = 0; i < pool.length; i++)
			lst.add(pool[i]);
		Collections.shuffle(lst, random);
		for (int i = 0; i < pool.length; i++)
			pool[i] = lst.get(i);
		// initialize rats
		bucket = new ArrayList<Rat>();
		// player
		player = new Player();
		player.init();

	}

	@Override
	public void update() {
		// get next bucket
		if (bucket.size() == 0) {
			int bucketSize = random.nextInt(BUCKET_SIZE + 1) + 1;
			for (int i = 0; i < bucketSize; i++)
				// TODO lawo baz
				bucket.add(pool[pool_index++ % pool.length].show());
		} else
			for (int i = 0; i < bucket.size(); i++)
				bucket.get(i).update();
		// player
		player.update();
		// active blocks
		for (int i = 0; i < ActiveTraps.size(); i++)
			ActiveTraps.get(i).update();
	}

	@Override
	public void draw(Canvas c, Paint p) {
		// update
		update();
		// background
		p.setColor(Color.DKGRAY);
		c.drawRect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, p);
		// board
		c.save();
		c.translate(SCREEN_XOFFSET, SCREEN_YOFFSET);
		c.translate(BOARD_XOFFSET, BOARD_YOFFSET * 2);
		p.setColor(Color.GRAY);
		c.drawRect(0, 0, BOARD_WIDTH, BOARD_HEIGHT, p);
		// holes
		c.scale(HOLE_SIZE * BOARD_SCALE, HOLE_SIZE * BOARD_SCALE);
		c.translate(.5f, .5f);
		p.setColor(Color.BLACK);
		for (int y = 0; y < HOLES_H; y++)
			for (int x = 0; x < HOLES_W; x++)
				c.drawCircle(x, y, .5f, p);
		// rats
		for (int i = 0; i < bucket.size(); i++)
			bucket.get(i).draw(c, p);
		// active blocks
		for (int i = 0; i < ActiveTraps.size(); i++) {
			// Log.d("block",
			// "active block position = "+ActiveBlocks.get(i).getPosition());
			ActiveTraps.get(i).draw(c, p);
		}

		// player
		p.setTypeface(Typeface.MONOSPACE);
		p.setTextSize(HOLE_SIZE / 4);
		c.restore();
		player.draw(c, p);
		// top bar
		p.setColor(Color.WHITE);
		p.setTextAlign(Align.LEFT);
		c.drawText(String.format("%02d", Player.time / 30), 0, -p.ascent(), p);
		if (Powerups.red_counter <= 0)
			p.setColor(Color.WHITE);
		else
			p.setColor(Color.RED);
		p.setTextAlign(Align.RIGHT);
		c.drawText(String.format("%05d", Player.score) + "$", SCREEN_WIDTH,
				-p.ascent(), p);

	}

	@Override
	public void draw(GL10 gl) {
		// TODO Auto-generated method stub

	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub

	}

	public static Rat getRat(int x, int y) {
		int pos = x + y * HOLES_W;
		Log.d("size", pos + "");
		for (int i = 0; i < bucket.size(); i++) {
			Log.d("size", bucket.get(i).position + " " + i);
			if (bucket.get(i).position == pos)
				return bucket.get(i);
		}
		return null;
	}

	public static Block getBlock(float x) {
		return MenuTool.getBlock(x);

	}

	public static void returnBlock(Block b) {
		MenuTool.returnBlock(b);
	}

	public static float getToolMenuHeight() {
		return (Player.drawer_y * Player.DRAWER_HEIGHT * Screen.HOLE_SIZE
				+ Screen.SCREEN_YOFFSET + Screen.BOARD_YOFFSET * 2);
	}

	public static void touch(MotionEvent e) {
		Log.d("size", e + " " + e.getAction());
		int x = (int) Math.floor((e.getX() - SCREEN_XOFFSET - BOARD_XOFFSET)
				/ HOLE_SIZE / BOARD_SCALE);
		int y = (int) Math
				.floor((e.getY() - SCREEN_YOFFSET - BOARD_YOFFSET * 2)
						/ HOLE_SIZE / BOARD_SCALE);

		// block
		// now i hold the block (trap,rat) and i need to ad it to the hole
		if (y < 0 && currentBlock != null) {
			returnBlock(currentBlock);
			currentBlock = null;
		}
		if (currentBlock != null) {
			Log.d("block", "x= "+x+" y= "+y);
			currentBlock.openBlock(x + y * HOLES_W);
			
			currentBlock = null;
		}
		// get the block
		if (Player.drawer_open) {
			if (e.getY() < getToolMenuHeight()) {
				currentBlock = getBlock(e.getX());
			}
			Player.drawer_open = false;
		}

		// drawer
		if (y < 0) {
			Player.drawer_open = !Player.drawer_open;

		}

		if (x < 0 || x >= HOLES_W || y < 0 || y >= HOLES_H)
			return;
		// kill
		if (e.getAction() == MotionEvent.ACTION_DOWN) {
			Rat r = getRat(x, y);
			if (r != null)
				r.kill();
		}
	}

}
